#include "cluster.h"
#include "../util.h"
#include "label_selector\freq_selector.h"

Cluster::Cluster(string line)
{
	init(line);
}

void Cluster::init(string line)
{
	int del1 = line.find("\t"), del2 = line.find("\t", del1 + 1);
	int cluster_size_s = atoi(line.substr(0, del1).c_str());

	id = line.substr(del1 + 1, del2 - del1 - 1);
	util::LogMgr::record(id + "\n");
	size = 0;
	string cluster_elem_s = line.substr(del2 + 1, line.length() - del2 - 1);
	vector<string> qf_list = util::tokenize_h(cluster_elem_s, " | ");
	for(int i = 0; i < qf_list.size(); ++ i)
	{
		string q_f = qf_list[i];
		int del = q_f.find("\t");
		string query = q_f.substr(0, del);
		string freq_c = q_f.substr(del + 1, q_f.length() - del - 1);
		int freq = atoi(freq_c.c_str());
		string q = util::format(query);
		graph.add_node(query);
		query2freq.insert(pair<string, int>(query, freq));
		size += freq;
	}
}
void Cluster::display(iostream* out, iostream* query, LabelSelector &selector)
{
	vector<vector<string>> groups;
	graph.flood(groups);
	stringstream res;
	for(int i = 0; i < groups.size(); ++ i)
	{
		stringstream group_info;
		group_info << id << "_" << i << "\t";
		int total = 0;
		map<int, vector<string>> sort_map;
		map<int, vector<string>>::iterator itr;
		vector<QueryNode> elem;
		for(int j = 0; j < groups[i].size(); ++ j)
			elem.push_back(graph.get_node(groups[i][j]));
		string label = selector.getLabel(elem);
		*query << id << "_" << i << "\t" << label << endl;
		int total_q = 0, cur_q = 0;
		for(int j = 0; j < groups[i].size(); ++ j)
		{
			string query = groups[i][j];
			total_q ++;
			int freq = (*query2freq.find(query)).second;
			itr = sort_map.find(-freq);
			if(itr == sort_map.end())
			{
				vector<string> v;
				v.push_back(query);
				sort_map.insert(pair<int, vector<string>>(-freq, v));
			}
			else
				(*itr).second.push_back(query);
			total += freq;
			
		}
		for(itr = sort_map.begin(); itr != sort_map.end(); ++ itr)
		{
			int freq = - (*itr).first;
			vector<string> &query_list = (*itr).second;
			for(int j = 0; j < query_list.size(); ++ j)
			{
				string query = query_list[j];
				group_info << query << "\t" << freq;
				if(++ cur_q < total_q)
					group_info << " | ";
			}
		}
		res << total << "\t" << group_info.str() << endl;
	}
	*out << res.str();
}
void Cluster::display(iostream* out)
{
	vector<vector<string>> groups;
	graph.flood(groups);
	stringstream res;
	for(int i = 0; i < groups.size(); ++ i)
	{
		stringstream group_info;
		group_info << id << "_" << i << "\t";
		int total = 0;
		map<int, vector<string>> sort_map;
		map<int, vector<string>>::iterator itr;
		int total_q = 0, cur_q = 0;
		for(int j = 0; j < groups[i].size(); ++ j)
		{
			string query = groups[i][j];
			total_q ++;
			int freq = (*query2freq.find(query)).second;
			itr = sort_map.find(-freq);
			if(itr == sort_map.end())
			{
				vector<string> v;
				v.push_back(query);
				sort_map.insert(pair<int, vector<string>>(-freq, v));
			}
			else
				(*itr).second.push_back(query);
			total += freq;
			
		}
		for(itr = sort_map.begin(); itr != sort_map.end(); ++ itr)
		{
			int freq = - (*itr).first;
			vector<string> &query_list = (*itr).second;
			for(int j = 0; j < query_list.size(); ++ j)
			{
				string query = query_list[j];
				group_info << query << "\t" << freq;
				if(++ cur_q < total_q)
					group_info << " | ";
			}
		}
		res << total << "\t" << group_info.str() << endl;
	}
	*out << res.str();
}

void Cluster::display_with_label(iostream* out, LabelSelector &selector)
{
	if(selector.instance == "FreqSelector"){
		FreqSelector* freq_selector = dynamic_cast<FreqSelector*>(&selector);
		freq_selector->init(query2freq);
	}
	vector<vector<string>> groups;
	graph.flood(groups);
	stringstream res;
	for(int i = 0; i < groups.size(); ++ i)
	{
		stringstream group_info;
		int total = 0;

		vector<QueryNode> elem;
		if(groups.size() == 0)continue;
		stringstream ss;
		for(int j = 0; j < groups[i].size(); ++ j)
			elem.push_back(graph.get_node(groups[i][j]));
		string label = selector.getLabel(elem);
		map<int, vector<string>> sort_map;
		map<int, vector<string>>::iterator itr;
		int total_q = 0, cur_q = 0;
		for(int j = 0; j < groups[i].size(); ++ j){
			string query = groups[i][j];
			total_q ++;
			int freq = (*query2freq.find(query)).second;
			itr = sort_map.find(-freq);
			if(itr == sort_map.end())
			{
				vector<string> v;
				v.push_back(query);
				sort_map.insert(pair<int, vector<string>>(-freq, v));
			}
			else
				(*itr).second.push_back(query);
			total += freq;
			
		}
		for(itr = sort_map.begin(); itr != sort_map.end(); ++ itr)
		{
			int freq = - (*itr).first;
			vector<string> &query_list = (*itr).second;
			for(int j = 0; j < query_list.size(); ++ j)
			{
				string query = query_list[j];
				group_info << query << "\t" << freq;
				if(++ cur_q < total_q)
					group_info << " | ";
			}
		}
		res << label << "\t"<< total << ":" << group_info.str() << endl;
	}
	*out << "{" << "cid:"<< id << "\t" << size << endl << res.str() << "}" << endl;
}